Method and system for executing a task and medium storing a program therefor

ABSTRACT

A method of executing a task includes executing, by using a processor, a first task including a low-frequency task in which garbage is collected using a garbage collector, initializing a second task including a high-frequency task by constructing an instance of a class that implements a standard runnable thread interface, and creating a data structure for supporting communication between the second task and lower priority threads, the data structure being accessible by a thread running in a garbage-collected heap in the first task to communicate data between the high-frequency task and the low-frequency task, validating the second task to ensure that the second task is executable without synchronizing with the first task, instantiating the second task to create a class for executing the second task; and after the instantiating the second task, executing the second task, the garbage collector being preemptable by the second task.

RELATED APPLICATIONS

This Application is a Continuation Application of U.S. patentapplication Ser. No. 11/449,774 filed on Jun. 9, 2006.

BACKGROUND OF THE INVENTION

1. Field of the Invention

The present invention relates to a method (and system) for executing atask and, more particularly, to a method of executing a task (e.g., alow latency task) which includes executing a second task, a garbagecollector in a first task being preemptable by the second task.

2. Description of the Related Art

The complexity of real-time systems is increasing rapidly as theisolated real-time controllers of the past give way to complex systemsin which many coordinated systems interact to create an integratedmulti-level real-time system, such as a car or a ship. In the face ofthis huge increase in complexity, traditional real-time methodologiesbased on low-level coding styles and fixed data structures are no longertenable.

Java's software engineering benefits have made it a compelling choicefor modular application development: memory safety, a standardized modelof concurrency, and a host of common libraries make it possible todevelop large and complex applications in a piecewise fashion. With thedevelopment of Metronome real-time garbage collection technology and theReal-Time Specification for Java (RTSJ) standard, Java has become aviable platform for the creation of such complex real-time systems.However, there are many problems remaining before a dynamic, garbagecollected language like Java can provide a complete real-time solutiondown to the lowest-level, highest-frequency applications.

Real-time garbage collection, as exemplified by the Metronome system, iscurrently able to achieve worst-case latencies on the order of amillisecond. This latency bound may scale down by another factor of twoto four as a result of improved implementation techniques. However,latency is limited by the need for atomic processing of certain datastructures, and by the overhead of context switching, especially sincethe collector tends to evict much of the application data from thecache.

As a result, real-time Java programmers with response time requirementsbelow a millisecond are currently forced to resort to the RTSJ'sNoHeapRealtimeThread (NHRT) construct. As its rather verbose monikerimplies, code executed by an NHRT is isolated from the garbage-collectedheap and may therefore be run concurrently with the collector orinterrupt it arbitrarily. However, NHRTs may only create and accessobjects in the manually-managed Immortal and Scoped memory areas.

Unfortunately, this requires fundamental changes to the semantics of theJava programming language. Scopes essentially provide region-basedmemory management with neither explicit region qualifiers nor implicitregion inference. As a result, the region restrictions of a method arenot documented in its interface and may vary dynamically based on itsinputs. This greatly lowers the level of abstraction of the language,requires expensive run-time checks, and makes it difficult to reasonabout the behavior of an object without understanding itsimplementation.

Most perniciously, NHRTs require dynamic checks on both reads and writesof reference fields to guarantee that region constraints are notviolated. These dynamic checks will throw exceptions when they fail,while reading or writing reference fields of an object in the heap willnever throw an exception. This represents a deep change to the languagesemantics and a significant obstacle to code re-use.

SUMMARY OF THE INVENTION

In view of the foregoing and other exemplary problems, drawbacks, anddisadvantages of the conventional systems and methods, a purpose of theexemplary aspects of the present invention is to provide a method (andsystem) of executing a task (e.g., a low latency task) that may besimpler to program and implement, more reliable and more efficient thanother approaches.

In an exemplary embodiment of the present invention, a method forexecuting a task (e.g., a low latency task) includes executing a firsttask in which garbage is collected using a garbage collector, andexecuting a second task, the garbage collector being preemptable (e.g.,preempted) by the second task.

In an exemplary aspect of the present invention, a second task (whichcan preempt the garbage collector) may have a lower latency (e.g.,higher frequency) than a first task.

In another embodiment of the present invention, a method of executing atask includes executing a first task in which garbage is collected usinga garbage collector, initializing a second task by: constructing aninstance of a class that implements a standard runnable threadinterface, and creating a data structure for supporting communicationand synchronization between the second task and lower priority threads(e.g., threads having a lower priority than the second task), validatingthe second task to ensure that the second task is executable withoutsynchronizing with the first task, instantiating the second task tocreate a class for the executing the second task by one of: creating anexecutable thread that will repeatedly invoke the second task, andassociating the second task with an interrupt handler and executing asecond task, the garbage collector being preemptable (e.g., preempted)by the second task.

In another exemplary embodiment of the present invention, a system forexecuting a task includes a first executing module for executing a firsttask in which garbage is collected using a garbage collector, and asecond executing module for executing a second task which preempts saidgarbage collector.

In another exemplary embodiment of the present invention, an interrupthandler for an operating system includes an interrupt module forinterrupting an operation in the operating system, and a system forexecuting a task including a first executing module for executing afirst task in which garbage is collected using a garbage collector, anda second executing module for executing a second task which isassociated with the interrupt module and the garbage collector beingpreemptable (e.g., preempted) by the second task.

Another exemplary embodiment of the present invention includes aprogrammable storage medium tangibly embodying a program ofmachine-readable instructions executable by a digital processingapparatus to perform a method of executing a task according to thepresent invention.

In another exemplary embodiment, the method according to the presentinvention may include deploying computing infrastructure in whichcomputer-readable code is integrated into a computing system, such thatthe code and the computing system combine to perform the executing ofthe first task in which garbage is collected using a garbage collector,and the executing a second task, the garbage collector being preemptable(e.g., preempted) by the second task.

With its unique and novel features, the present invention provides amethod (and system) of executing a task (e.g., a low latency task) whichmay be simpler to program and implement, more reliable and moreefficient than other approaches.

BRIEF DESCRIPTION OF THE DRAWINGS

The foregoing and other exemplary purposes, aspects and advantages willbe better understood from the following detailed description of anexemplary embodiment of the invention with reference to the drawings, inwhich:

FIG. 1 illustrates a method 100 of executing a task according to anexemplary aspect of the present invention;

FIG. 2 illustrates a method 200 of executing a task according to anexemplary aspect of the present invention;

FIG. 3 illustrates a system 300 for executing a task according to anexemplary aspect of the present invention;

FIG. 4 illustrates code for implementing a low-frequency task accordingto an exemplary aspect of the present invention; according to anexemplary aspect of the present invention;

FIG. 5 illustrates code for implementing a high-frequency task accordingto an exemplary aspect of the present invention;

FIG. 6 illustrates code for implementing task integration according toan exemplary aspect of the present invention;

FIG. 7 illustrates a system 700 for executing a task according to anexemplary aspect of the present invention; according to an exemplaryaspect of the present invention;

FIGS. 8A and 8B provide code for operations that may be illegalaccording to an exemplary aspect of the present invention;

FIG. 9 illustrates how an interface to run-time support operations maybe added to a virtual machine to support the Construct according to anexemplary aspect of the present invention;

FIG. 10 provides Table 1 which includes Validation times for severalexemplary Constructs according to an exemplary aspect of the presentinvention;

FIGS. 11-14 provide histogram plots which present the results fromexperiments conducted by the inventors;

FIG. 15 illustrates an oscilloscope view of a Construct according to anexemplary aspect of the present invention;

FIGS. 16-17 provide histogram plots which present the results fromexperiments conducted by the inventors;

FIG. 18 illustrates a typical hardware configuration which may be usedfor implementing the system and method according to the exemplaryaspects of the present invention; and

FIG. 19 illustrates a programmable storage medium 1900 tangiblyembodying a program of machine-readable instructions executable by adigital processing apparatus to perform the method according to theexemplary aspects of the present invention.

DETAILED DESCRIPTION OF EXEMPLARY EMBODIMENTS OF THE INVENTION

Referring now to the drawings, and more particularly to FIGS. 1-19,there are shown exemplary embodiments of the method and structures ofthe present invention.

FIG. 1 illustrates a method 100 for executing a task according to anexemplary aspect of the present invention. The method 100 includesexecuting (110) a first task in which garbage is collected using agarbage collector, and executing (120) a second task, the garbagecollector being preemptable (e.g., preempted) by the second task.

In an exemplary aspect of the present invention, a second task (whichcan preempt the garbage collector) may have a lower latency (e.g.,higher frequency) than a first task.

FIG. 2 illustrates method 200 for executing a task according to anotherexemplary aspect of the present invention. The method 200 includesexecuting (210) a first task in which garbage is collected using agarbage collector, initializing (220) a second task by constructing aninstance of a class that implements a standard Runnable threadinterface, and creating a data structure for supporting communicationand synchronization between the second task and lower priority threads(e.g., threads having a lower priority than the second task), validating(230) the second task to ensure that the second task is executablewithout synchronizing with the first task, instantiating (240) thesecond task to create a class for the executing the second task by oneof creating an executable thread that will repeatedly invoke the secondtask, and associating the second task with an interrupt handler, andexecuting (250) a second task, the garbage collector being preemptable(e.g., preempted) by the second task.

FIG. 3 illustrates a system 300 (e.g., a software implemented system)for executing a task (e.g., a low latency task), according to anexemplary aspect of the present invention. The system 300 includes afirst executing module 310 for executing a first task in which garbageis collected using a garbage collector 311, and a second executingmodule 320 (e.g., a new programming construct) for executing a secondtask having a higher frequency than the first task, the garbagecollector being preemptable (e.g., preempted) by the second task.

As illustrated in FIG. 3, the first executing module 310 may receivedata for executing a first task and output a result of executing a firsttask, and the second executing module 320 may receive data for executinga second task and output a result of executing a second task.

The system 300 may also include an initializing module 330 forinitializing the second task by constructing an instance of a class thatimplements a standard Java Runnable interface, and creating a datastructure for supporting communication and synchronization between thesecond task and low-frequency threads, and a validating module 340 forvalidating the second task to ensure that the second task is executablewithout synchronizing with the first task, and an instantiating module350 for instantiating the second task to create a class for theexecuting the second task.

Further, the instantiating module 350 may include a tracker 351 fortracking a set of objects which are accessible by the second task, and apinner 352 for pinning the objects such that the objects are immovableby the first task.

Overview

While real-time garbage collection has achieved worst-case latencies onthe order of a millisecond, this technology is approaching its practicallimits. For tasks requiring extremely low latency, and especiallyperiodic tasks with frequencies above 1 KHz, Java programmers mustcurrently resort to the NoHeapRealtimeThread construct of the Real-TimeSpecification for Java. This technique requires expensive run-timechecks, can result in unpredictable low-level exceptions, and inhibitscommunication with the rest of the garbage-collected application.

The present invention, on the other hand, includes a new programmingconstruct that can arbitrarily preempt the garbage collector, and mayguarantee safety and allow its data to be visible to thegarbage-collected heap. The programming construct according to thepresent invention may be a strict subset of Java, and require norun-time memory access checks. Safety may be enforced using adata-sensitive analysis and simple run-time support with extremely lowoverhead.

The inventors have implemented the programming construct in a Javavirtual machine, in experiments in which the construct was run atfrequencies up to 22 KHz (a 45 μs period). Across 10 million periods,99.997% of the executions ran within 10 μs of their deadline, comparedto 99.999% of the executions of the equivalent program written in C.

Detailed Discussion

The present invention includes a programming construct (e.g.,“Construct”) for tasks that can arbitrarily preempt a garbage collectorand yet may be comprised entirely of standard Java code without extrarun-time memory access checks. This programming construct (e.g., thesecond executing module 310 in FIG. 3) according to the presentinvention may be simple to design, develop, and understand. Theprogramming construct can also be terminated in the event of costover-run without causing deadlocks or data structure corruption.

It should be noted that the inventors implemented an exemplary aspect ofthe present invention using a Construct which they named “Eventron”.Thus, there may be referenced to the term Eventron herein. However, thisterm should in no way be considered limiting and, in fact, basically anyterm may be substituted for the term Eventron herein.

Specifically, other terms may be substituted for the term “Eventron” inthe programming code discussed herein. Thus, for example, the Constructaccording to an exemplary aspect of the present invention may beentitled “Construct X” in which case the term“ConstructXReadChannelofShort” may be substituted for the term“EventronReadChannelOfShort” discussed herein, and so forth.

The new programming construct may be both more and less restrictive thanNHRTs and Scopes. Allocation within the new programming construct maynot be permitted, and neither may be modification of pointers. Theserestrictions may be enforced at validation time using a simple bytecodeanalysis. Once the Construct is validated, it may not throw anyexceptions except those resulting from normal Java semantics such asarray bounds checking.

The Construct may be less restrictive than Scopes because theconstruct's data structures can be accessed by normal Java threadsrunning in the garbage collected heap. As a result, communication ofdata between high-frequency tasks, and lower frequency,garbage-collected tasks is greatly simplified.

Validation occurs at run-time, examining both the code and the data ofthe construct, but must be performed before the Construct may bescheduled. By choosing this intermediate point between fully static andfully dynamic checking, we are able to perform a simple analysis whoserestrictions are easy for programmers to understand, and yet obtain afairly precise call graph since it is based on a known set of previouslyinstantiated objects. The separation of the program into an“initialization” and a “mission” phase is also natural to most real-timeapplications.

The Construct is well suited to tasks like sensor processing, in whichsensor data must be sampled at a very high frequency, buffered, and thenprocessed en masse by a lower-frequency task.

The Construct is also well-suited to simple high-frequency control loopsthat read a limited amount of data, perform some simple processing (suchas FFTs) and then produce actuator control values. The ability to sharedata between high-and low-frequency tasks allows the use of morecomplex, dynamically allocated, garbage-collected data structures in thelow-frequency tasks that make higher-level planning decisions requiringmore complex processing.

The combination of the Construct for high-frequency tasks and real-timegarbage collection for medium-to low-frequency tasks provides anintegrated programming methodology that enables the use ofheap-allocated data structures in even the most demanding real-timeapplications, and yet does not change the Java programming model in anyfundamental way.

Example: Music Generation

We begin with an example to illustrate the use of the Construct toimplement an integrated real-time application. The example combines bothlow- and high-frequency tasks to generate and play back music withoutrelying on the operating system or underlying hardware to buffer theoutput. A low-frequency task performs the computation necessary tocompose a musical score and generate the raw audio data, while ahigh-frequency task sends the raw audio data to the unbuffered outputdevice, one sample at a time. To provide seamless audio playback at thestandard frequency of 22.05 KHz, the high-frequency task in this examplemust be run every 45 μs.

Implementing a Low-Frequency Task

FIG. 4 illustrates a program for executing a low-frequency task. Thistask generates the next note of a musical score, converts the note to anarray of samples, and then writes the samples to a shared channel.

That is, the task in FIG. 4 may use a music composition library (notshown) to generate a musical score one note at a time. Each note is thenconverted to a set of samples and written to a shared channel. Thelow-frequency task (including any libraries it uses) may rely on agarbage collector to automatically manage memory; the code used toimplement this task may only be constrained at the point where itinteracts with the high-frequency task.

In this example, that interaction may be managed by anEventronReadChannelOfShort. This general purpose data structure mayprovide a form of impedance matching between the low-and high-frequencytasks and can be configured to hide the latency and jitter of thelow-frequency task. While the code shown in FIG. 4 may allocate an arrayfrom which the raw audio samples are copied into the channel queue, thechannel queue also provides a mechanism to avoid this copy.

Implementing a High-Frequency Task

FIG. 5 illustrates a program for a high-frequency task, according to anexemplary aspect of the present invention. This task may reads a single16-bit sample from the shared channel and play it using an interface tothe raw audio device.

The high-frequency task in FIG. 5 may be implemented using the Constructabstraction. During an iteration (e.g., each iteration), the task mayread a single 16-bit sample from the shared channel and write thatsample out to the audio device.

A number of constraints may be enforced on the Construct code duringinitialization using an on-line analysis. For example, note thatreference fields may be declared final on lines 2-6. The inventors foundthat the use of final may be a natural and familiar way to ensure thatthe Construct data structure remains fixed over time.

The high-frequency task may use the non-blocking interface of theEventronChannel to read individual samples. This operation may returneither a sample or a value indicating that the channel is empty orclosed. Alternatively, programmers can avoid reserving special indicatorvalues and instead use exceptions. However, all exceptions should (e.g.,must) be preallocated, as also illustrated in the example.

This task in FIG. 5 also uses a native method (lines 9 and 19) tocommunicate with the audio playback device. Many applications of theConstruct may require native methods to communicate with hardware. TheConstruct run-time takes steps to ensure the relative safety of Javanative interface (JNI) code that is invoked by a Construct.

Notice that the high-frequency task does not necessarily contain alooping construct. Instead, the scheduler may invoke this taskperiodically as indicated during initialization. The Construct maycontinue to be invoked until it is explicitly removed from thescheduling queue (by some other thread), or when an exception is thrownfrom the Construct run( ) method.

Integrating Tasks

FIG. 6 illustrates a program for task integration, according to anexemplary aspect of the present invention. The two tasks may beinstantiated, initialized with a shared channel queue, and thehigh-frequency task may be validated before being passed to thescheduler.

That is, FIG. 6 provides an example of integration of the low-andhigh-frequency tasks. On line 11 in FIG. 6, the programmer mayinstantiate a shared data structure which is the sole mechanism forinteraction between the low-and high-frequency tasks. The low-frequencytask may be scheduled on lines 18 and 19 by instantiating an ordinaryJava thread.

Before the high-frequency task can be executed, it may be first bevalidated (line 16) to ensure that it can safely preempt the collector.While validation may fail and cause a checked exception to be thrown inthe main( ) method, memory access checks are not necessarily performedwhile executing the Construct.

Thus errors may occur during the initialization phase of the applicationinstead of during the execution of the Construct itself. This is anatural time to detect any problems in the configuration of theConstruct, as the application should also ensure that any requiredhardware is properly configured and that sufficient resources areavailable to run the Construct.

Validation may also cause the run-time system to pin down any datastructures accessible by the Construct: these objects may not becollected or even moved to another location in the heap while theConstruct is active. However, once the Construct is disabled, theseobjects can be moved and, if they are otherwise unreachable, reclaimed.

The Life and Times of the Construct

FIG. 7 provides an example of a system 700 (e.g., a software-implementedsystem) in which the Construct 701 may interact with the heap 710,according to an exemplary aspect of the present invention. In addition,the heap 710 may be accessible by the stack 705 and global 715. Further,the Construct 701 may include buffers 703 which may store values in theconstruct, to provide efficient access to the values.

Objects 702 associated with a Construct 701 may reside in thegarbage-collected heap 710 but may be pinned for the life of theConstruct. The objects 702 may be referenced by other heap objects 711,and may be subject to garbage collection once the Construct 701terminates.

The Construct 701 may defined by a set of Java methods that may beexecuted as a high-frequency task, the data structures manipulated bythose methods, and a thread that will execute them. In the presentinvention, Constructs 701 can safely preempt the virtual machine, and inparticular the garbage collector, at any point by eliminating anysynchronization between Constructs 701 and the collector.

First, it is ensured that the Constructs 701 cannot change thereachability of any object managed by the collector. While thiscondition might be enforced by additional run-time checks, the presentinvention may instead impose constraints on the code and data structuresdefining a Construct 701 that can be verified before the Construct 701is executed. These constraints ensure that the set of objects accessibleto a Construct 701 is fixed for the duration of its execution, whileallowing objects used by a Construct 701 to be accessed by ordinary Javathreads. These constraints may be enforced using a run-time staticanalysis: an analysis of the Construct bytecode may be performed whilethe program is executing, but before the Construct itself is invoked.This may allow an efficient and precise analysis.

Secondly, the need for synchronization between the garbage collector anda Construct 701 may be eliminated by precluding any collector operationsthat, if preempted by a Construct 701, might expose the heap 710 in aninconsistent state. Specifically, objects accessible to a Construct 701may be pinned. Thus, the collector may never be interrupted while movingone of the Construct's objects.

The lifetime of a Construct 701 may be split into five phases. First, aConstruct 701 may be initialized in the same way an ordinary Javastructure is constructed. During the second phase, validation, thepresent invention may verify that the Construct 701 code can safelypreempt the collector and discover (e.g., simultaneously discover) theset of objects that should be pinned.

The third phase is instantiation, in which the Construct's datastructure may be pinned and an executable thread may be created. Thefourth phase is execution, during which the Construct 701 may be invokedone or more times, either at specific times, with a predeterminedperiod, or in response to certain external events. Finally, a Constructmay be destroyed, at which point the objects in its data structure maybe unpinned and eventually garbage collected, unless the objects arereachable from the heap 710 or other Constructs 701.

Initialization

To create a Construct, the programmer may construct an instance of aclass that implements the standard Java Runnable interface. This objectmay form the root of the Construct data structure, and its run( ) methodmay form the entrypoint for the execution of the Construct.

The programmer may also build the data structures necessary to supportcommunication and synchronization between the Construct andlow-frequency threads. Typically, this may involve the use of one ormore channels.

Validation

During the validation phase, the present invention may ensure that aConstruct may be safely executed without synchronizing with the garbagecollector (i.e., the collector). Validation may take place while theapplication is running but before the Construct is invoked. This mayallow the validation process to take advantage of information that ispresent at run-time and to detect potentially misbehaving code while thetask is being set up rather than during the execution of the Constructitself.

Validation should (e.g., must) ensure three features of the Constructcode: first, that the Construct code does not allocate any memory,second, that the Construct code does not perform any blockingoperations, and third, that the extent of the heap that it accessesremains fixed.

These restrictions may be enforced by creating a data-specific callgraph for the particular Construct being validated, and performing a setof checks on the bytecodes of the resulting methods. This process can beviewed as a kind of partial evaluation.

Enforcement of Restrictions

FIGS. 5A and 5B provides a list of operations that may be illegal inConstruct code. Specifically, FIG. 5A provides a table which includesillegal bytecodes in Construct code and FIG. 5B provides a list ofillegal method invocations in Construct code.

Operations that may be illegal within a Construct are summarized in FIG.5A. When any of these operations are encountered, aConstructValidationException is thrown reporting the source codelocation of the offending instruction.

As shown in FIG. 5A, bytecodes (e.g., all bycodes) that performallocation may be prohibited, as well as bytecodes that performsynchronization either explicitly (via monitor bytecodes) or implicitly(via synchronized methods). As further shown in FIG. 5B, reflectiveaccess to such operations may also be prohibited, as is the use of thewait and notify methods of Object (which would necessarily generateexceptions since the Construct thread is never able to enter a monitor).

The last group of restrictions in FIG. 5A may ensures that Constructsneither read nor update mutable heap references. Writes to objectfields, static variables, and array elements may only be permitted forprimitive types. Reads are permitted for non-primitive types, but onlyif the field is declared final.

There are at least two complications with respect to final fields:first, Java does not provide any mechanism to specify the immutabilityof array elements. To this end, the present invention may provide aspecial class, ImmutableArray<T>, which stores an array of immutablereferences to objects of class T.

An ImmutableArray may be initialized by passing it an array ofreferences, which is copied into a private instance array of theImmutableArray object. The only methods provided are get(index) andlength( ). Since the finality of the array elements within anImmutableArray is enforced programmatically, the validator allows theiruse within a Construct.

The reflective analogues may get and set of the proscribedpointer-accessing bytecodes may also be prohibited. Note that unlike thebyte-code operations, the reflective operations may be more restricted,since at validation time the fields or methods being accessed may not beknown. In particular, neither reflective access to final pointer fieldsnor reflective method invocation may be permitted within a Construct.

The second complication with respect to finality has to do with exposureof incompletely constructed objects. This problem may be solved in thepresent invention by using a simple run-time assisted mechanism.

In practice, the inventors found that rejecting all methods that performallocation may inhibit the reuse of some existing library methods insidethe Construct. This is often due to the common Java idiom of allocatingexception objects (“throw new FooException”). In many cases, theprogrammer knows that the offending code will never be executed but thevalidator conservatively assumes otherwise. An optional feature of thevalidator allows programmers to exempt certain methods from the normalcheck for allocating bytecodes. To keep this feature from compromisingsafety, the run-time allocator may throw an immediate OutOfMemoryErrorwhenever an allocation occurs on a Construct thread.

Data-Sensitive Call Graph Analysis

The validator's analysis may explore the set of reachable methods andthe set of reachable objects (e.g., simultaneously), letting each setinform the other. Rather than build a complete call graph, the validatormay analyze only those methods that could be invoked given the set ofobjects reachable by the Construct. In the course of its analysis, thevalidator may conservatively determine sets of objects O, fieldsignatures F, methods M, and virtual method signatures V reachable tothe Construct. These are the structures which may be accessed by theConstruct during its execution.

Initially, O may contain only the object implementing the Runnableinterface, and the only method in M is its run( ) method. For eachmethod added to the call graph, the validator may consider eachbyte-code instruction of that method in turn. Note that each method maybe analyzed at most one time, and therefore the validator may terminatein time linear in the size of the program and the size of the heap.

-   -   getfield—The signature of target field f is added to the        validation set F. In addition, the validator may consider every        object in O that defines a field matching that signature. For        every such object, the validator may use reflection to determine        the referent of its field f; this referent may then added to O.

As objects are added to O, each one should (e.g., must) be inspected forfields that are already found in F, and the referents of these fieldsshould be added to O. Therefore, in the course of processing a singlegetfield instruction, only one field signature may be added to F, butmany objects may be added to O.

-   -   getstatic—The validator may add (e.g., immediately add) the        referent of the static field to O. Any fields of the referent        that appear in F are considered as above.    -   invokestatic, invokespecial—For method invocations whose targets        can be statically determined, the validator may add the target        method to M.    -   invokeinterface, invokevirtual—For virtual method invocations,        the signature of the target method may be added to V. The        validator may then consider each object in O implementing that        signature. For each such object, its implementation may be added        to M and subsequently validated.

Just as the fields of objects added to O may (e.g., must) be compared tothe signatures in F, the methods of those objects may (e.g., must) becompared to the signatures in V. That is, for an object (e.g., eachobject) added to O, and for a method (e.g., each method) m of thatobject, if m matches a signature in V, then m may be added to M.

Finally, the restrictions described above may be enforced as the method(e.g., each method) is processed. If a prohibited bytecode instructionor method invocation appears in an analyzed method body, the analysismay terminate immediately, throwing an exception that indicates wherethe offending code can be found.

If the validation succeeds, the objects in O may be those that may beaccessed by the Construct and therefore should (e.g., must) be pinned.

Recall that any reference field (instance or static) accessed by aConstruct may (e.g., must) be declared final. This restriction may beused not only to ensure that synchronization with the collector can besafely omitted, it may also be helpful (e.g., necessary) for thesoundness of the above analysis. Without this restriction, the validatormay not be able to safely assume which objects may occupy a given fieldor which implementations of a given method signature might be invoked.

Because the present invention may require only those fields that mightbe referenced by a Construct to be declared final, some reference fieldsin the Construct data structure may not be final. As a result, pinnedobjects may hold (mutable) references to unpinned objects, as shown inFIG. 7. This is safe since the inventors' analysis has shown that thesefields may not be accessed by the Construct.

Data-Sensitive Analysis versus Other Analyses

Note that the analysis utilized by the present invention may be neitherflow-sensitive nor context-sensitive. It may be however, data-sensitive:the call graph may be constructed for the invocation of the run( )method of a particular concrete Construct instance. In general, flow-and context-sensitivity can increase the precision of call graphanalysis. However, even fairly aggressive algorithms still make someconservative approximations, especially about the contents of instancefields, which can induce imprecision in the call graph.

JIT compilers may often compensate for the imprecision of static callgraph construction algorithms by exploiting profile data, online classhierarchy analysis, and other optimistic and speculative optimizations.This often works well in practice, but if the assumption turns out to beinvalid, the code may need to be (e.g., must be) recompiled (anoperation that may not necessarily mesh well with real-time execution).

In principle, a data-sensitive analysis may be more or less precise thanany of the above techniques, depending on the particular classhierarchies, call graphs, and execution orders. However, the inventorsbelieve that a data-sensitive analysis may often yield the most preciseresult in practice.

Regardless of the precision, however, there is at least one morecompelling reason to use data-sensitive analysis: it may be simpleenough that it can be easily described to a programmer. More complexanalyses are easily perturbed by small changes in the code, and aseemingly trivial change can cause two variables to become possiblyaliased.

The analysis used by the present invention may avoid this form ofspeculation and rely on two forms of information which may be specified(e.g., specified directly) by the user: the object graph and the use offinal fields. In contrast to other analyses, the data-sensitive analysisin the exemplary aspects of the present invention may use mechanismsthat may be familiar to Java programmers and may yield an induced callgraph that may be quite stable in the face of changes to the program.

Implementation

The present invention may implement the validation phase using acombination of standard Java reflection (to explore the graph ofreachable objects) and specialized VM-specific code to consult thebytecodes and constant pool of already loaded and validated classes(validation may (e.g., must) run against the in-memory classes toprevent security attacks that change the class files).

It may be straightforward to implement the same validation algorithmusing a class file inspection package, with or without a static analysisframework (for example, an earlier prototype used the Domo programanalysis library). However, such a validator may only be safe to use fordevelopment-time exploration of Construct validity. A run-time validatormay (e.g., must) ensure that it is working with the actual bytecodesthat have been loaded into the running VM.

Preventing Violations of Finality

To help ensure complete safety of Construct execution, some additionalchecks may be required for code that executes outside of the Constructthreads.

Exposure of Incompletely Constructed Objects

Unfortunately, simply using final may not guarantee that heap structureswill be immutable. A constructor may expose the pointer before theconstructor's fields are completely initialized, for instance by storingthis into a static field. If a partially constructed object is presentin a Construct data structure, the validator may see a final field asnull even though it will be subsequently initialized to a non-nullvalue. In this case, the validator may have based its analysis onincomplete information, and the safety of the Construct could becompromised.

Attempts to prevent such operations via static analyses tend to begrossly over-conservative because the targets of virtual calls are notavailable.

An exemplary aspect of the present invention, however, provides asolution which may include adding a “fully constructed” flag to theheader of an object (e.g., every object). The interpreter may set thisflag as a constructor returns (the return of any constructor for a givenclass is sufficient to guarantee that final fields of that class and itssuperclasses are initialized). The present invention may provide arun-time interface allowing the flag to be queried, and the validatormay throw an exception whenever it encounters an object for which thisflag is not set. This may result in a simple programming model and anefficient implementation.

The specification to the programmer may be simple: all Construct objectsmust be completely constructed.

Reflection and JNI

It may also be possible to undermine the restrictions of final usingreflection. The method invocation restrictions on Construct code (FIG.8B) may already rule out any reflective access to pointers in theConstruct data structure from the Construct itself. However, otherthreads may have full access to reflection, and in Java 1.5, reflectionmay even allow the modification of final fields (!) after a call tosetAccessible( ).

According to the specification, this functionality may only be intendedto be used during deserialization and other uses may have “unpredictableeffects.” However, any violation of finality may render Constructsunsafe, which the inventors do not consider to be an acceptable“unpredictable effect,” so this should be prevented.

In an exemplary aspect of the present invention , a preferred approachto this problem may include modifying the Field.set( ) implementation ofjava.lang.reflect to check whether the field being set is a final fieldof an object pinned by a Construct. In that case, a run-time exceptionmay be thrown. Similarly, Array.set( ) can be modified to preventreflective modification of pointers inside the arrays that implement theImmutableArray class.

Restrictions on reflective field access should not cause runtimeexceptions in code that uses the interface as intended, since Constructdata structures may be constructed before validation, and so bydefinition are not necessarily being de-serialized.

Similar to reflection, JNI code can circumvent Construct restrictionsand violate validation assumptions. For example, native code can executeJava methods that were not part of the validation-time call graph, readand write reference fields that the validator did not know were to beread or written, enter monitors, or allocate objects. Despite this, manyConstructs must use native code to interface with hardware devices.

One could argue that JNI code is inherently unsafe since it is capableof directly modifying any word in memory (indeed, no JNI access controlrestrictions are enforced in the Java programming language as adeliberate design decision). However, the inventors judged that JNI codethat was completely safe to execute in other contexts ought not toproduce arbitrary results simply because it was invoked by a Construct.

The present invention may catch native code violations with inexpensivedynamic checks in those JNI helper functions that should not be calledby Constructs. Each helper function that would be unsafe to execute on aConstruct thread may immediately throw an exception if executed on aConstruct thread. This allows problems to be caught early in the testingphase (albeit not necessarily at validation time).

Instantiation

Once a Construct has been validated, it should (e.g., must) beinstantiated. This may involve (e.g., requires) either creating anexecutable thread that will invoke the Construct repeatedly at highfrequency, or associating the Construct with an interrupt handler. Ineither case, the run-time system should (e.g., must) also track the setof objects accessible to the Construct and pin these objects so thatthey are not moved by the garbage collector. The set ofConstruct-reachable objects may be created during the validation phase(to avoid redundant object traversals) and may be now installed into therun-time data structures. This set may be external to the Constructitself and persist until the Construct is destroyed.

Pinning of Construct Objects

For Constructs to work properly in conjunction with a collector thatmoves objects (whether or not the collector is incremental), the objectsshould (e.g., must) be pinned before the Construct is allowed toexecute.

FIG. 9 illustrates how Interfaces to run-time support operations may beadded to the virtual machine to support the Constructs (e.g.,Eventrons).

There are various collector architectures that move objects, among thempage-based defragmenting collectors, generational collectors, andsemi-space copying collectors, as well as their concurrent variants(although the present invention is not necessarily limited to anyparticular type of garbage collector). There are also various approachesto pinning objects suited to the different kinds of collectorarchitectures. For instance, in a generational collector, objects shouldnot be pinned in the nursery, so a nursery evacuation should be forcedas part of the Construct instantiation procedure.

The present invention is described herein based on the design used inthe inventors' actual implementation that runs together with theMetronome collector, a real-time incremental collector that organizesmemory into page-based segregated free lists (although the presentinvention is not limited thereto). Defragmentation may be performed onan as-needed basis and compact objects within a size class.

To minimize changes to the Java run-time system, the inventors' chose toimplement the run-time support for Constructs in Java whenever possible.One exception includes support for pinning objects. In an exemplaryaspect, the inventors extended the interface to the run-time system withthe functions shown in FIG. 9.

Invoking pinObjects may prevent the objects from being moved by thecollector. Invoking unpinObjects may revert this state change. Only theConstruct run-time support code may have access to the pinning andunpinning methods. The native support may be wrapped by Java code thataggregates pinning information from multiple Constructs. These nativemethods may be called (e.g., are only called) with collections ofobjects the first time those objects are used by a Construct or once allConstructs using those objects have terminated.

This interface may be similar to the Create/DestroyGlobalRef functionsfound in the Java Native Interface. While those functions may ensurethat a given object will not be freed, they do not necessarily guaranteethat the referent will not be relocated by the collector. Though nostandard support for pinned objects may exist in Java, several otherlanguages may already provide similar functionality. For example, theabove interface can be easily implemented using existing run-timesupport in either the Common Language Runtime or the Haskell ForeignFunction Interface.

Since Metronome uses a page-based memory architecture, theimplementation in an exemplary aspect of the present invention ofpinning may maintain a count of the number of pin operations applied tothe objects of each page. At instantiation time, pinObjects( ) may beinvoked with the set of objects that are accessible to the Construct butthat are not already pinned. Since pinning may be atomic with respect tointerleavings with the garbage collector, once the entire data structurehas been pinned, it may be guaranteed that the collector will not moveany of the objects.

Compensating for Races with Compaction

However, this does not necessarily guarantee collector independence:there may be pointers among the objects that were pinned early in thisstage that refer to objects that were later pinned but moved by thecollector in the intervening time. Thus, there may be stale pointers inthe Construct data structure. For the garbage-collected heap, this maynot be a problem since those pointers will be fixed during thesubsequent tracing phase of the collector before the old versions ofobjects are reaped.

Unlike ordinary Java threads, the Construct's stack is not necessarilyscanned to identify roots or fix stale pointers once it beginsexecution. Thus, a Construct could potentially load a stale pointer intoa stack variable and dereference it after the old object (with itsforwarding pointer) had been reaped by the collector and re-allocated.

This problem may be addressed by performing a second iteration over theConstruct objects after pinning is completed. The two-phase nature ofobject pinning and forwarding may be part of the implementation ofpinObjects. The second iteration may check whether any pointers in theobject are stale and immediately update them to the forwarded copy ofthe referent.

This second pass may guarantee that no stale pointers remain in anyConstruct object. After this point, no Construct object may be moved bythe collector nor may any Construct object contain pointers that will bemodified by the collector. Therefore, the Construct stack may nevercontain stale references and does not need to be examined, and at nopoint in the Construct's execution should (e.g., must) it synchronizewith the collector.

Once all Construct objects are pinned and their pointers are forwarded,a Construct thread may be created. The run-time may ensure thatbecomeEventronThread is invoked for each Construct so that it may bedistinguished from ordinary Java threads.

Execution

Thread Priorities

Once a Construct is released, it may arbitrarily preempt the garbagecollector. Constructs by default may be created with a priority justhigher than the thread that schedules the garbage collector (whichitself may run at a priority just higher than the collector threadsthemselves).

Construct priorities may be set to any value allowed by the underlyingsystem. Constructs may co-exist with RTSJ NoHeapRealTimeThreads, andtheir relative scheduling may be handled by the operating system basedon their respective priorities.

Distinguishing Construct Threads

Construct threads should (e.g., must) not yield to garbage collectionthreads at the beginning of each collector quantum. Therefore, anexemplary aspect of the present invention may distinguish Constructthreads using a flag in a thread-specific data structure. This flag maybe used by the run-time scheduler to determine which threads must reacha safe point before a collection quantum can begin. In addition, as thecollector is scanning the stack of each application thread, it should(e.g., must) ignore the stacks of Construct threads since these threadsare not necessarily at safe points.

Because the stacks of Construct threads are not necessarily scannedduring collection, it should (e.g, must) be ensured that any objectaccessible to a Construct is also reachable from some other root. Theset of pinned objects associated with each Construct may serve tomaintain this invariant: each set of pinned objects may be added to aglobal table for the duration of the execution of the Construct.

Construct threads may share some characteristics withNoHeapRealtimeThreads, for example, neither may be suspended during theexecution of the collector. However, these two types of threads may bedistinguished, as Constructs are not necessarily subject to the samechecks on heap access.

Run-Time Exceptions

While the inventors' analysis may rule out any allocation that may occurbecause of code intentionally written by the programmer, the presentinvention may allow the programmer to relax this restriction for codeincluded from libraries, meaning that unanticipated allocations mayoccur, causing an immediate OutOfMemoryError. In addition, the systemmay perform allocation while handling an exceptional condition thatarises during normal execution (e.g., NullPointerException).

The inventors found it impractical to change all of the code pathsinvolved, and typically the run-time does much more than allocate anexception object (e.g., it also allocates a string of message text). Inan exemplary aspect (e.g., the inventors' implementation), theseallocations may also cause an immediate OutOfMemoryError. Despite this,the inventors' implementation may ensure that all such exceptionscontain valid traceback information, which simplifies debugging.

Exceptions may be caught by a Construct, including both those exceptionsthat are preallocated and those that arise from allocation. Unhandledexceptions may result in the termination of the execution phase. TheConstruct may (e.g., will) not be re-run until it is explicitlyrescheduled.

Termination

Once a Construct has run its course, either after it has been disabledby a call from another thread, or because it threw or failed to catch anexception, its data structures may be unpinned and the Construct threadmay revert to the ordinary state for a brief interval beforeterminating. During this brief interval, the Construct thread may storeinto reference fields, and this may explain how exceptions thrown duringthe execution phase may be preserved for inspection by other threads.

When a Construct is destroyed, the destruction routine may unpin theassociated data structure, so that Construct objects that remain livedue to pointers from the mutable heap may be no longer pinned, and theremay be no “pinning leak.”

Killing, Restarting, and Cost Enforcement

Since Constructs do not necessarily modify pointer structures and do notnecessarily hold locks (because all operations should (e.g., must) benon-blocking), it should be possible to terminate a Construct at anyinstruction without negative effects on the rest of the system.

This avoids another major problem with other approaches tohigh-frequency tasks in Java, namely that they may hold resources whichmay make the semantics of early termination poorly defined.

The only circumstance under which killing Constructs is unsafe may bewhen the program is using a custom synchronization protocol in which theConstruct might expose partially updated state non-atomically. However,as long as the channel abstractions are used this should (e.g., will)not happen.

This capability can be used to implement either asynchronous terminationof the entire Construct or of one particular execution. This may meshwell with cost enforcement, since it may allow the early termination ofan iteration that misses its deadline, and may immediately reset it to astate in which it can handle the next event in a timely fashion.

Construct Channels

To aid programmers in transferring data between tasks of differentpriorities and frequencies, an exemplary aspect of the present inventionmay provide an implementation of wait-free, allocation-free channels.These channels may allow data to be streamed to and from Constructtasks. Though the inventors intended that EventronChannels may be commonutility classes, they may still be checked by the validation processdescribed above.

An exemplary aspect of the present invention may also provide the lowerlevel Notifier object (discussed below as part of the implementation ofEventronChannels). The Notifier, along with the properties of the Javamemory model and/or the facilities of the java.util.concurrent.atomicpackage, can be used to implement other wait-free utilities.

EventronChannels should (e.g., must) be wait-free to avoid priorityinversion. An exemplary aspect of the present invention may provide twoversions of the channel abstraction: one that provides wait-free accessto the reader and a blocking interface to the writer (called aEventronReadChannel) and another that provides a symmetric interface(EventronWriteChannel). (The present invention may also providewait-free access for the low-priority half of these channels.) This mayallow for relatively straightforward implementations of both high- andlow-frequency tasks: high-frequency tasks may be driven by thescheduler, and if they avoid looping and use only wait-free structuressuch as ConstructChannels, they should have predictable execution times.Low-frequency tasks can be designed to produce or process data asquickly as possible and can rely on the channel to throttle theirexecution.

Channels should (e.g., must) also be free of allocation and pointermutation to avoid synchronization with the collector. Like otherConstruct data structures, they should (e.g., must) perform allallocation during initialization. An exemplary aspect of the presentinvention may specialize EventronChannels for the single reader/singlewriter case to allow efficient implementation in the context of theseconstraints.

Each EventronChannel may provide a wait-free communication mechanism byimplementing a circular queue or ring of primitive values. These valuesmay be grouped together into buffers to provide more efficient access.EventronChannels may come in seven “flavors,” one for each of the eachof the primitive Java types.

Programming Interface

At their core, ConstructChannels may be similar to input and outputstreams, providing methods to read and write individual elements andarrays of them. In the most basic interface, reading (respectively,writing) an array of values may cause the elements of the array to becopied from (respectively, to) the internal data structure.

However, the present invention may also offer a slightly more complex,but lower overhead, alternative. A reader or writer may also acquireaccess to the internal buffer array. This may allow data to betransferred between (e.g., directly between) tasks without anyadditional copies. Programmers should (e.g., must) be careful torelinquish references (e.g., all references) to a buffer once it hasbeen released for use by the other task. Failure to do so may lead tounexpected values being read from the channel.

In many applications, when a channel overrun or underrun occurs, thehigh-frequency task should (e.g., must) continue to execute either bydiscarding data (in the former case) or using a default value (in thelatter), while the error itself should be handled by some other task.EventronChannels may provide a mechanism to automatically communicatethese exceptional conditions back to the low-frequency task: asubsequent write (read) performed by the low-frequency task may throw anUnderrunException (OverrunException).

Configuration

Two important (e.g., the most important) channel configurationparameters include the number of buffers and the size of each buffer. Bydividing the channel storage into a fixed set of buffers, the presentinvention may allow the programmer to control the rate ofsynchronization between the reader and the writer. Each buffer may beowned by at most one of the two processes, allowing efficient access inthe common case.

Only when moving from one buffer to the next may atomic memory accesses(e.g., compare-and-swap) be required. The size and number of buffersshould (e.g., must) be determined given the relative jitter of the twotasks. The size of each buffer may determine the minimum latency betweenwhen values are written to and read from the channel, and the number ofbuffers may determine the maximum such latency.

In the audio playback example, a primary source of latency for thelow-frequency task is the garbage collector. Suppose in this examplethat one is able to guarantee a maximum pause time of 5 ms and a minimummutator utilization of 50% over any 10 ms window. Then, the properconfiguration may include three buffers each containing 5 ms of data or,equivalently, 111 samples (recall that our example uses 22.05 kHzaudio).

Initially the (low-frequency) writer may (e.g., will) be 10 ms ahead ofthe reader, but due to interruptions by the garbage collector, it maylag behind to the point where it is only 5 ms ahead. Such a scenario may(e.g., will) only occur if the collector has consumed a significantportion of the previous scheduling quanta: by the present invention'sminimum utilization guarantee, the collector may (e.g., will) consumeless of the subsequent quanta and allow the synthesizer to speed aheadonce again.

The EventronWriteChannel may have one additional configurationparameter. In the case of an overrun, some data will be lost: either theoldest data should (e.g., must) be overwritten, or the newest should(e.g., must be discarded. An exemplary aspect of the present invention(e.g., the inventors' implementation) may support both, leaving theprogrammer to determine which is most appropriate for a givenapplication.

Implementation

Each EventronChannel may be implemented using an ImmutableArray ofBufferState objects, where such objects may encapsulate a buffer and aninteger state variable. The state of each buffer may determine both thestate of the content (whether the buffer contains data or not) and whoowns the buffer. For example, a buffer (e.g., each buffer) in aEventronReadChannel may be empty, full, reading, or writing, the lasttwo indicating ownership by the reader or writer, respectively.

There may be two additional states, underrun and closed, that may beused to communicate changes in the status of the channel as a whole.When an underrun occurs, the reader may wrest ownership of the currentbuffer from the writer, setting its state to underrun. The next accessby the writer may (e.g., will) discover the state change and throwexception. Analogously, the writer may indicate the end of the datastream by setting the state of its current buffer to closed.

EventronChannels may depend on atomic operations provided by theJava.util.concurrent.atomic package. Atomic compare-and-swap operationsmay be used to update the state of each buffer. For example, an underrunmay occur at the same moment that the writer finishes writing to abuffer. Both tasks may attempt to update the state of this buffer (tounderrun and full, respectively). An atomic update may ensure that bothtasks agree on the winner of the race.

Further, the implementation of channels may require a mechanism to allowthe high-frequency task to notify the low-frequency one when a bufferbecomes available. The standard Java lock-notify-unlock may beunsuitable and while the implementation of locks injava.util.concurrent.locks may include tryLock and signal operationsthat avoid synchronization, they may not perform allocation and pointermutation, rendering them unusable by Constructs. (This is partly becausethese locks may support an unbounded number of waiters.) Instead, anexemplary aspect of the present invention may provide a Notifier classthat wraps any Object. That is, an exemplary aspect of the presentinvention may provide a notifyIfWaiting method, implemented internallyto the virtual machine, which notifies threads (if any) waiting on thewrapped object's lock without blocking, allocating, or updating anyreference field.

Evaluation

The present inventors have tested the performance of both validation andexecution of Constructs, in particular comparing them to equivalent Cprograms and evaluating the interference from other (garbage collected)JVM threads.

All experiments were run on an IBM Intellistation Z Pro with 2 Pentium 4Xeon processors (at 2.4 GHz and with 2-way hyperthreading) and 2 GB ofphysical memory. The operating system is Linux with the 2.6.14 kernel.Additionally, various patches to improve real-time performance wereapplied including high-resolution timers (HRT) and robust mutexes forpriority inheritance.

The base for the implementation is IBM's Real-Time edition of the J9virtual machine, which includes the Metronome garbage collector, RTSJ,and an ahead-of-time compiler. The language level is 1.5 (with generics)using the J2SE libraries.

The inventors' prototype implementation of Constructs included the“fully constructed” check and safety checks for reflective fieldupdates. Although, in the inventor's experiments the aspects of theConstruct prototype were not integrated into the production VM used togather the results reported below, based on earlier experiments with theprototype implementation, the inventors do not believe this materiallyimpacts the results reported below.

All Constructs were run at 22.05 KHz (a 45.35 μs period), a standardfrequency for digital audio. Tests were run until 10,000,000 sampleswere obtained. These runs were sufficiently large to encompass periodicoperating system activity which could perturb the results and to providea statistically meaningful comparison. For example, the operating systemflushes data to the disk every 30 seconds and performs timer interruptsevery 1 millisecond.

Validation

FIG. 10 provides Table 1 which includes Validation times for severalexemplary Constructs. The Null Construct has a trivial run( ) method,Audible is the music generation example, and FFT computes a fast Fouriertransform.

The inventors measured the time required to validate this small set ofexemplary Contructs. Table 1 shows the size of these examples and thetime required to validate them. Each example includes any library codethat may be executed by the Construct, for example, some methods ofEventronReadChannelOfShort in the Audible example. While thesevalidation times are much longer than the execution of the Constructsthemselves, validation must only be performed once per instantiation ofa Construct.

Base Performance: Constructs versus C

To establish the base timeliness results of Constructs, we implemented aC program which uses the same OS function calls to establish a periodictask of the same 22.05 KHz frequency. Other than computation toestablish the scheduling behavior, neither version performs any work.The inventors measured the timeliness of both versions by measuring theinterarrival times of the Construct and C handler.

Noting that the y-axis is logarithmic, FIG. 11 shows that nearly all ofthe data is centered tightly around the target period time of 45.3 μs.More precisely, 99.64% of the samples lie within 5 μs of the targettime. Within 10 μs of the target time, Constructs include 99.997% of thedata while C includes 99.999% of the samples.

Both the C version and the Construct versions have nearly the samedistribution, both in terms of the extent and count of both the outlierclusters and the main region. This curve represents the degree to whichthis particular version of Linux is real-time and represents the best wecan achieve from user-level code.

In this graph, the histogram's x-axis ends at 120 μs although there isone additional group of outliers centered at 4.0 ms. In fact, all runs,regardless of whether it is C or Constructs, which version ofConstructs, and the load under which it is run, suffer from the sameeffect. Thus, the inventors believe that the effect stems from theoperating system effect such as sync-ing the disk. In this particularfigure, the C version has 12 outliers ranging from 3.93 to 4.06 ms whilethe Construct version has 7 outliers ranging from 3.99 to 4.05 ms. This4.0 ms effect is pervasive and stems from the operating system.

Timeliness in the Presence of GC

Having established that Constructs can potentially achieve latencysimilar to that of a C application, we now test the main design featureof Constructs by measuring the effect that garbage collection has onConstruct interarrival times. To do this, the Construct was run togetherwith a lower-priority Java thread that continually allocates, thustriggering periodic garbage collections. The Construct's scheduling ispotentially affected by both the mutator thread and the garbagecollection thread.

As seen in FIG. 12, these two effects combine to slightly worsen thebehavior of the Construct. The distribution is not as tight as before sothat at 10 μs, 99.990% of the data is included. However, nearly all ofthe distribution lies within 25 μs of the target time. In fact, the tailof the distribution is better when the mutator thread and the garbagecollection threads are enabled.

To demonstrate the effectiveness with which Constructs address thelatency problem, the the Construct was replaced with an equivalent Javaversion which runs at high priority. FIG. 13 shows that the interarrivaltimes of a regular Java thread are far worse than that of a Construct.In fact, the outliers are so distant that we extended the x-axis from130 μs to 1 ms. The number of outliers increases by a factor of 20, andthese outliers are centered around 550 μs which is slightly greater thanthe time the garbage collection thread typically runs for. Fornon-realtime garbage collectors, the interarrival times would be evenworse.

Performance Under Load: Constructs with CPU-bound Threads

After having established that the base performance of Constructs may besimilar to that of a similar C application, the inventors tested theperformance of Constructs when run in conjunction with regular Javathreads in a single Java VM. To stress the system, the inventors chosefour benchmarks from the SPECjvm98 suite (db, jack, javac, andmpegaudio) which are CPU-bound batch applications so that the threadsare almost always eligible to run.

As FIG. 14 shows, the Constructs are slightly less timely when thesystem is under load and the deviation is dependent on the load. Withdb, the deviation is small, and 99.990% of the data falls within a 10 μswindow. On the other hand, javac causes greater perturbations, and a 10μs window includes only 99.986% of the samples. While these numbers arestill very high, the differences are significant and show that otherthreads do cause definite perturbations. Because this version of Linuxdoes not have the pre-emption patches (which at the time were toounstable), various system calls can cause the kernel to enter criticalsections in which it will not yield. For example, a lower-prioritythread can request a non-blocking I/O operation which nonetheless willblock an unrelated Construct thread.

FIG. 15 shows the passage of time as a series of strips or “scan lines”moving from left to right and then top to bottom. A Construct (darkgray) was executed every 45 μs. The width of oscilloscope view isexactly four times the period of the Construct, thus the Constructexecutions line up vertically. The alarm task (part of the GC scheduler)is shown in black and runs with a period of 200 μs, slightly longer thanthe width of the view, resulting in the staggering effect. Finally theGC execution is shown in light gray. Note that the Construct continuesto run at fixed intervals despite the execution of the other tasks.

Interaction with Low-Frequency Tasks: Audible Constructs

The inventors tested the performance of the audible Construct that wasdescribed above. In addition to showing perturbation from thelower-priority low-frequency task, this example demonstrates that thewait-free channels perform as described. Since the audible Constructwrites to /dev/dsp, timing anomalies may arise from operating systeminteractions. In fact, despite using non-blocking I/O, the system callwrite periodically takes quite a while.

Because this anomaly is not necessarily central to the Construct designbut deals with lower-level aspects of specific devices, we first presentperformance result without the write in FIG. 16. There are nosignificant changes to the tail of the distribution although the centralportion of the distribution grows slightly wider similar to effect ofgarbage collection in FIG. 12. The similarity suggests that theoperating system does not always promptly schedule high-priority threadseven when there is no interaction (via mutexes, for example) between thehigh- and low-priority threads.

Further, the inventors showed the pronounced effect of including thecall to write in the audible Construct in FIG. 17. There is clearly acluster of data centering around 200 μs. Examination of the raw datashows that every 93 ms, the call to write takes up to 220 μs instead ofthe usual 2 μs. The audio card performs double buffering and each bufferis 2048 samples in size. At 22050 Hz, this corresponds to 93 ms so webelieve that, despite opening /dev/dsp with non-blocking I/O (which didimprove matters), certain calls are still affected by bufferingoperations within the kernel.

Advantages over Related Art

Construct validation may involve constructing a call graph and analyzingit to detect violations of the programming model. A wide range of callgraph construction algorithms have been described. Static analyses havealso been adapted to operate on-line and handle Java language featuressuch as reflection, dynamic class loading, and JNI. However, unlike allof this previous work, the present invention may include a Constructvalidator which may analyze the code in the context of the exact objectinstances on which it will operate. This may significantly simplifyanalysis since the actual object instance can be reflectively examinedto determine the types and contents of its fields.

The Real-Time Specification for Java (RTSJ) is a standard that defines anumber of extensions and changes to the virtual machine and standardJava libraries to support real-time application development. The RTSJdefines NoHeapRealtimeThreads (NHRTs) as the proper high frequencytasks. NHRTs are forbidden from accessing any object allocated in thegarbage-collected heap. Instead, NHRTs may allocate from either theImmortalMemoryArea or one of the ScopedMemoryAreas. Objects allocated inthe former will be preserved for the remainder of the life of thevirtual machine; thus the ImmortalMemoryArea is suitable for only thoseobjects that are allocated during the initialization phase of anapplication.

Programming effectively and safely with RTSJ scoped memory is widelyrecognized as being quite challenging.

Static type systems have been proposed to make it easier to writecorrect programs using RTSJ's scoped memory abstractions. In thesesystems, correctly typed programs cannot cause memory access violations,therefore all of the RTSJ mandated dynamic memory checks can beeliminated. Such systems statically partition heap connectivity, butallow real time tasks to dynamically allocate memory (using RTSJ scopedmemory) within their heap partition. In a Construct programming modelaccording to an exemplary aspect of the present invention, however, heapconnectivity may not be restricted but dynamic memory allocation by theConstruct may be forbidden.

Other related art has reported on a detailed performance comparison of ajRate RTSJ implementation and the RTSJ reference implementation (RI)from TimeSys. One relevant data point from these experiments is that itwas observed that the RTSJ RI Periodic Thread implementation was onlyable to achieve predictable behavior for tasks with periods greater thanor equal to 30 ms. Higher frequency tasks suffered significant jitter.In contrast, a Construct Implementation according to an exemplary aspectof the present invention may be capable of achieving highly predictablebehavior for tasks with periods as small as 45 μs.

Conclusion

Constructs according to the exemplary aspect of the present inventionmay provide a simple and elegant means of writing tasks requiringextremely low latency while co-existing with a garbage-collectedlanguage. By taking advantage of Java's existing final mechanism,augmented with some run-time support to eliminate loopholes that couldcompromise safety, a simple data-sensitive analysis may be able toguarantee safety before Constructs begin executing. Constructs may besimpler to program, simpler to implement, more reliable, and moreefficient than other approaches like scoped memory.

Constructs may make it feasible to program almost any real-time systementirely in pure Java code. Further, Constructs may be used to directlygenerate CD-quality audio waveforms and to write device drivers. Theinventors believe that Constructs may make it possible to replace eventhe lowest levels of system software with safe code in a managedrun-time system.

Another exemplary embodiment of the present invention includes aninterrupt handler (e.g., in an operating system) which may be in agarbage collected language. The interrupt handler includes an interruptmodule for interrupting an operation in the operating system, and asystem for executing a task, including a first executing module forexecuting a first task in which garbage is collected using a garbagecollector, and a second executing module for executing a second taskwhich is associated with the interrupt module, the second task having ahigher frequency than the first task, and the garbage collector beingpreemptable by the second task.

Referring again to the drawings, FIG. 18 illustrates a typical hardwareconfiguration which may be used for implementing the computer system andmethod according to the exemplary aspects of the present invention. Theconfiguration has preferably at least one processor or centralprocessing unit (CPU) 1811. The CPUs 1811 are interconnected via asystem bus 1812 to a random access memory (RAM) 1814, read-only memory(ROM) 1816, input/output (I/O) adapter 1818 (for connecting peripheraldevices such as disk units 1821 and tape drives 1840 to the bus 1812),user interface adapter 1822 (for connecting a keyboard 1824, mouse 1826,speaker 1828, microphone 1832, and/or other user interface device to thebus 1812), a communication adapter 1834 for connecting an informationhandling system to a data processing network, the Internet, andIntranet, a personal area network (PAN), etc., and a display adapter1836 for connecting the bus 1812 to a display device 1838 and/or printer1839. Further, an automated reader/scanner 1841 may be included. Suchreaders/scanners are commercially available from many sources.

In addition to the system described above, a different aspect of theinvention includes a computer-implemented method for performing theabove method. As an example, this method may be implemented in theparticular environment discussed above.

Such a method may be implemented, for example, by operating a computer,as embodied by a digital data processing apparatus, to execute asequence of machine-readable instructions. These instructions may residein various types of signal-bearing media.

Thus, this aspect of the present invention is directed to a programmedproduct, including signal-bearing media tangibly embodying a program ofmachine-readable instructions executable by a digital data processor toperform the above method.

Such a method may be implemented, for example, by operating the CPU 1811to execute a sequence of machine-readable instructions. Theseinstructions may reside in various types of signal bearing media.

Thus, this aspect of the present invention is directed to a programmedproduct, including signal-bearing media tangibly embodying a program ofmachine-readable instructions executable by a digital data processorincorporating the CPU 1811 and hardware above, to perform the method ofthe invention.

This signal-bearing media may include, for example, a RAM containedwithin the CPU 1811, as represented by the fast-access storage forexample. Alternatively, the instructions may be contained in anothersignal-bearing media, such as a magnetic data storage diskette 1900(FIG. 19), directly or indirectly accessible by the CPU 1811.

Whether contained in the computer server/CPU 1811, or elsewhere, theinstructions may be stored on a variety of machine-readable data storagemedia, such as DASD storage (e.g, a conventional “hard drive” or a RAIDarray), magnetic tape, electronic read-only memory (e.g., ROM, EPROM, orEEPROM), an optical storage device (e.g., CD-ROM, WORM, DVD, digitaloptical tape, etc.), paper “punch” cards, or other suitablesignal-bearing media. In an illustrative embodiment of the invention,the machine-readable instructions may comprise software object code,complied from a language such as “C” etc.

With its unique and novel features, the present invention provides amethod (and system) of executing a task (e.g., a low latency task) whichmay be simpler to program and implement, more reliable and moreefficient than other approaches.

It should be noted that while an exemplary aspect of the presentinvention has been described as being implemented using the Javaprogramming language, the present invention is not necessarily limitedto Java. That is, the present invention may be implemented using anygarbage collected programming language.

While the invention has been described in terms of one or more exemplaryembodiments, those skilled in the art will recognize that the inventioncan be practiced with modification within the spirit and scope of theappended claims. Specifically, one of ordinary skill in the art willunderstand that the drawings herein are meant to be illustrative, andthe design of the inventive assembly is not limited to that disclosedherein but may be modified within the spirit and scope of the presentinvention.

Further, Applicant's intent is to encompass the equivalents of all claimelements, and no amendment to any claim the present application shouldbe construed as a disclaimer of any interest in or right to anequivalent of any element or feature of the amended claim.

1. A method of executing a task, comprising: executing, by using aprocessor, a first task comprising a low-frequency task in which garbageis collected using a garbage collector; initializing a second taskcomprising a high-frequency task by: constructing an instance of a classthat implements a standard runnable thread interface; and creating adata structure for supporting communication between said second task andlower priority threads, said data structure being accessible by a threadrunning in a garbage-collected heap in said first task to communicatedata between said high-frequency task and said low-frequency task;validating said second task to ensure that said second task isexecutable without synchronizing with said first task; instantiatingsaid second task to create a class for executing said second task; andafter said instantiating said second task, executing said second task,said garbage collector being preemptable by said second task.
 2. Themethod of claim 1, wherein said validating said second task comprisesdetermining a set of objects (O), a set of field signatures (F), a setof methods (M), and a set of virtual method signatures (V) which areaccessible by said second task.
 3. The method of claim 2, wherein saiddetermining said set of objects comprises a data-sensitive analysis. 4.The method of claim 1, wherein said instantiating said second taskcomprises: creating an executable thread that will repeatedly invokesaid second task; tracking said set of objects which are accessible bysaid second task; pinning said objects such that said objects areimmovable by said first task; extending an interface to a run-timesystem with second task run-time support code for supporting saidpinning of said objects; performing another pinning of said objects todetermine if any pointers in said objects are stale and, if stalepointers are determined, updating said stale pointers; forwardingpointers for objects associated with said second task; and installing aset of objects which are accessible by said second task into run-timedata structures such that said set of objects is external to said secondtask.
 5. The method of claim 4, wherein only said second task run-timesupport code has access to said pinning said objects and unpinning saidpinned objects.
 6. The method of claim 1, wherein said executing saidsecond task comprises: performing an allocation while handling anexceptional condition during said executing said second task.
 7. Themethod of claim 1, wherein said executing said second task furthercomprises: adding a set of pinned objects to a global table for aduration of executing said second task to ensure that any objectaccessible to said second task is accessible from another root.
 8. Themethod of claim 1, wherein said second task is implemented usingstandard programming language constructs and wherein objects associatedwith said second task are automatically discovered by the run-timesystem.
 9. The method of claim 1, wherein objects associated with saidsecond task reside in a garbage-collected heap, are referenceable byother objects in said garbage-collected heap, are pinned during a lifeof said second task, and are subject to garbage collection upontermination of said second task.
 10. The method of claim 1, wherein saidexecuting said second task is performed without executing a run-timememory access check.
 11. The method of claim 1, wherein said validatingsaid second task comprises adding an identifier to a header of anobject.
 12. The method of claim 1, wherein in said executing said secondtask, a priority of said second task is higher than a thread thatschedules said first task.
 13. The method of claim 1, wherein a threadfor said executing said second task is distinguished from a thread forexecuting said first task by using a flag in a thread-specific datastructure, said flag being used by a run-time scheduler to determinewhich threads should reach a safe point before a collection quantumbegins.
 14. The method of claim 1, wherein said second task isterminatable at any instruction without negatively effecting a remainderof a system in which said second task is executed.
 15. The method ofclaim 1, wherein said frequency of said second task comprises a samplingfrequency.
 16. The method of claim 1, wherein said low-frequency taskcomprises a first frequency and said high-frequency comprises a secondfrequency greater than said first frequency.
 17. The method of claim 1,wherein said low-frequency and high-frequency tasks are instantiated andinitialized with a shared channel queue, and the high-frequency task isvalidated before being passed to a scheduler, wherein said schedulerperiodically invokes the high-frequency task, and wherein saidvalidating said second task is performed while an application is runningand before said second task is invoked.
 18. The method of claim 1,wherein said validating said second task comprises creating adata-specific call graph for the data structure, and performing a set ofchecks on bytecodes of resulting methods.
 19. A system for executing atask, comprising: a first executing module for executing a first taskcomprising a low-frequency task in which garbage is collected using agarbage collector; an initializing module for initializing a second taskcomprising a high-frequency task by: constructing an instance of a classthat implements a standard runnable thread interface; and creating adata structure for supporting communication between said second task andlower priority threads, said data structure being accessible by a threadrunning in a garbage-collected heap in said first task to communicatedata between said high-frequency task and said low-frequency task; avalidating module for validating said second task to ensure that saidsecond task is executable without synchronizing with said first task; aninstantiating module for instantiating said second task to create aclass for executing said second task; and a second executing module for,after said instantiating said second task, executing said second task,said garbage collector being preemptable by said second task.
 20. Aprogrammable storage medium tangibly embodying a program ofmachine-readable instructions executable by a digital processingapparatus to perform a method of executing a task, the methodcomprising: executing, by using a processor, a first task comprising alow-frequency task in which garbage is collected using a garbagecollector; initializing a second task comprising a high-frequency taskby: constructing an instance of a class that implements a standardrunnable thread interface; and creating a data structure for supportingcommunication between said second task and lower priority threads, saiddata structure being accessible by a thread running in agarbage-collected heap in said first task to communicate data betweensaid high-frequency task and said low-frequency task; validating saidsecond task to ensure that said second task is executable withoutsynchronizing with said first task; instantiating said second task tocreate a class for executing said second task; and after saidinstantiating said second task, executing said second task, said garbagecollector being preemptable by said second task.